require "Common/define"
require "Logic/Config"
require "Common/functions"
require "Net/TrialHandel"
---@class TrialsManager
TrialsManager = {};
local this = TrialsManager;
function TrialsManager.init()
    this.trialsInfo = {};
    this.trialsConfig = {};
    this.trialsWorkRank = nil;--世界排行
    this.trialsFriendRank = nil;--好友排行
    this.myRankInfo = {};
    this.battleInfo = {};--上次排行信息
    this.recodeInfos = {};
    this.version = -1;
    this.recordVersion = -1;
    local config = dataTable.getDataTable("t_trials");
    for k, v in pairs(config) do
        v["f_TrialsCharacteristics"] = decodeJsonStrToTabel(v["f_TrialsCharacteristics"]);
        this.trialsConfig[k] = v;
    end

    this.levelDatas = {}
    this.durationDatas = {}
    this.buffDatas = {}
    local tableData = dataTable.getDataTable("t_trialsmodel")
    for _, v in pairs(tableData) do
        local type = tonumber(v["f_Type"])
        local id   = tonumber(v["f_Id"])
        local options = decodeJsonStrToTabel(v["f_Option"])
        local scores  = decodeJsonStrToTabel(v["f_Integral"])
        local method  = tonumber(v["f_IntegralType"])
        if 1 == type then
            local descTexts = decodeJsonStrToTabel(v["f_Packing"])
            this.levelDatas = { options = options, scores = scores, method = method, desc = descTexts }
        elseif 2 == type then
            this.durationDatas = { options = options, scores = scores, method = method }
        elseif 3 == type then
            table.insert(this.buffDatas, { id = id, options = options, scores = scores, method = method })
        end
    end
    table.sort(this.buffDatas, function(a, b) return a.id < b.id end)
end

function TrialsManager.GetTrialsInfo()
    return clone(this.trialsInfo);
end

function TrialsManager.GetTrialsConfig()
    return clone(this.trialsConfig);
end

function TrialsManager.GetFriendRank()
    return clone(this.trialsFriendRank);
end

function TrialsManager.GetWorkRank()
    return clone(this.trialsWorkRank);
end

function TrialsManager.GetMyRankInfo()
    return clone(this.myRankInfo);
end

function TrialsManager.GetBattleInfo()
    return clone(this.battleInfo);
end

function TrialsManager.GetTrialsRecordInfo()
    return clone(this.recodeInfos);
end

function TrialsManager.SetBattleDamage(data)
    this.trialsInfo.maxDamage = tonumber(tostring(data.maxDamage));
    this.trialsInfo.maxLevel = data.maxLevel;
    this.trialsInfo.maxScore = data.maxScore and tonumber(tostring(data.maxScore)) or 0;
end

function TrialsManager.SetBattleInfo(data)
    this.battleInfo.rank = data.rank + 1;
    this.battleInfo.damage = tostring(data.damage);
    this.battleInfo.score = data.score and tonumber(tostring(data.score)) or 0;
end

function TrialsManager.SetTrialsInfo(data)
    this.trialsInfo.endTime = data.endTime and tonumber(tostring(data.endTime));
    this.trialsInfo.nextTrialsId = data.nextTrialsId;
    this.trialsInfo.maxLevel = data.maxLevel;
    this.trialsInfo.maxDamage = tonumber(tostring(data.maxDamage));
    this.trialsInfo.maxScore = data.maxScore and tonumber(tostring(data.maxScore)) or 0;
    this.trialsInfo.trialsId = data.trialsId;
    this.trialsInfo.skillId = data.skillId;
    this.trialsInfo.nextSkillId = data.nextskillId;
    this.myRankInfo.workRank = data.rank + 1;
    this.trialsInfo.lastDayRewardTime = tonumber(tostring(data.lastDayRewardTime))

    logicMgr.FormationManager.SetFormation(EnumConst.FormationType.TrialsChaos, data.formation);--设置阵容

    logicMgr.TATrackCollect.Track_Chaos()
end

function TrialsManager.GetLastDayReward()
    if this.trialsInfo.lastDayRewardTime then
        return this.trialsInfo.lastDayRewardTime
    end
    return 0
end

--- @param data ResTrialsWorldRankMessage
function TrialsManager.SetTrialsRank(data)
    --if this.version ~= data.version then
    this.version = data.version;
    this.trialsWorkRank = data.rankList;
    this.myRankInfo.level = data.myLevel;
    this.myRankInfo.workRank = data.myRank + 1;
    this.myRankInfo.damage = tonumber(tostring(data.myDamage));
    this.myRankInfo.score = data.myScore and tonumber(tostring(data.myScore)) or 0;
    --end
end

function TrialsManager.SetTrialsFriendRank(data)
    this.myRankInfo.level = data.myLevel;
    this.myRankInfo.friendRank = data.myRank + 1;
    this.myRankInfo.damage = tonumber(tostring(data.myDamage));
    this.trialsFriendRank = data.rankList;
end

function TrialsManager.SetTrialsRecordInfo(data)
    this.recodeInfos.recordVersion = int64ToNumber(data.version);
    this.recodeInfos.records = data.records;
end

function TrialsManager.GetBossConfigByIdAndLevel(id, level)
    local cfgs = dataTable.getDataTable("t_trialsboss");
    for k, v in pairs(cfgs) do
        if v["f_TrialsSort"] == id and v["f_TrialsBossLayer"] == level then
            return v;
        end
    end
    return nil;
end

function TrialsManager.GetBossConfigById(id)
    local cfgs = dataTable.getDataTable("t_trials");
    for k, v in pairs(cfgs) do
        if v["f_TrialsBossId"] == tonumber(id) then
            return v;
        end
    end
    return nil;
end

function TrialsManager.enterTrials()
    local flag = GetPlayerPrefsAfter5AMFlag("_enter_trials:")
    if flag then
        SetPlayerPrefsAfter5AMFlag("_enter_trials:")
        RedDotsTrialHandler.Check()
        --local h = tonumber(os.date("%H", time));
        --if h * 60 * 60 >= G.dataTable["t_global"][tostring(34)].f_int_value then
            --Util.SetPlayerPrefs(logicMgr.HeroManager.GetRoleInfo().playerId.."_enter_trials:", os.date("%Y-%m-%d", time))
        --    RedDotsTrialHandler.Check()
        --end
    end
end

function TrialsManager.hasRedPoint()
    local flag = GetPlayerPrefsAfter5AMFlag("_enter_trials:")
    if flag then
        return true;
    end
    return false;
end

function TrialsManager.getBossPower()
    return this.trialsConfig[tostring(this.trialsInfo.trialsId or 1)].f_TrialsAbility;
end

local mLevelPoint    = nil
local mDurationPoint = nil
local mBuffPoint     = nil

--- 获取试炼难度积分倍率
---@return number
function TrialsManager.getLevelPoint()
    if mLevelPoint == nil then
        mLevelPoint = 1
        local currLevel  = logicMgr.TrialsManager.loadTrialsLevel()
        local levelDatas = this.levelDatas
        for i = 1, #levelDatas.options do
            if levelDatas.options[i] == currLevel then
                mLevelPoint = levelDatas.scores[i]
                break
            end
        end
    end

    return mLevelPoint
end
function TrialsManager.setLevelPoint(point)
    mLevelPoint = point
end

--- 获取试炼时长积分倍率
---@return number
function TrialsManager.getDurationPoint()
    if mDurationPoint == nil then
        mDurationPoint = 1
        local currDuration  = logicMgr.TrialsManager.loadTrialsDuration()
        local durationDatas = this.durationDatas
        for i = 1, #durationDatas.options do
            if durationDatas.options[i] == currDuration then
                mDurationPoint = durationDatas.scores[i]
                break
            end
        end
    end

    return mDurationPoint
end
function TrialsManager.setDurationPoint(point)
    mDurationPoint = point
end

--- 获取试炼buff积分倍率
---@return number
function TrialsManager.getBuffPoint()
    if mBuffPoint == nil then
        mBuffPoint = 0
        local currBuffs = logicMgr.TrialsManager.loadTrialsBuff()
        local buffDatas = this.buffDatas
        for i = 1, #buffDatas do
            local data = buffDatas[i]
            for j = 1, #data.options do
                local id, score = data.options[j], data.scores[j]
                if table.contains(currBuffs, id) then
                    mBuffPoint = mBuffPoint + score
                end
            end
        end
    end

    return mBuffPoint
end
function TrialsManager.setBuffPoint(point)
    mBuffPoint = point
end

--- 获取试炼难度配置
---@return {options: number[], scores: number[], method: number}
function TrialsManager.getLevelDatas()
    return clone(this.levelDatas or {})
end
--- 获取试炼时间配置
---@return {options: number[], scores: number[], method: number}
function TrialsManager.getDurationsDatas()
    return clone(this.durationDatas or {})
end
--- 获取试炼Buff配置
---@return {options: number[], scores: number[], method: number}[]
function TrialsManager.getBuffDatas()
    return clone(this.buffDatas or {})
end

--- 存储试炼难度等级
---@param level number 试炼难度
function TrialsManager.saveTrialsLevel(level)
    SetPlayerPrefs("k_trials_level", tostring(level))
end
--- 加载试炼难度等级
---@return number
function TrialsManager.loadTrialsLevel()
    local data = GetPlayerPrefs("k_trials_level")
    if data == nil then
        if this.levelDatas ~= nil then
            return tonumber(this.levelDatas.options[1])
        end
        return 60
    end
    return tonumber(data)
end

--- 存储试炼时长
---@param duration number 试炼时长
function TrialsManager.saveTrialsDuration(duration)
    SetPlayerPrefs("k_trials_duration", tostring(duration))
end
--- 加载试炼时长
---@return number
function TrialsManager.loadTrialsDuration()
    local data = GetPlayerPrefs("k_trials_duration")
    if data == nil then
        if this.durationDatas ~= nil then
            return tonumber(this.durationDatas.options[1])
        end
        return 60
    end
    return tonumber(data)
end

--- 存储试炼buff
---@param list number[] buff列表
function TrialsManager.saveTrialsBuff(list)
    SetPlayerPrefs("k_trials_buff", getJsonStr(list))
end
--- 加载试炼buff
---@return number[]
function TrialsManager.loadTrialsBuff()
    local data = GetPlayerPrefs("k_trials_buff")
    if data == nil then
        return {}
    end
    return decodeJsonStrToTabel(data)
end

return TrialsManager;